﻿using AsmShaderConverter.AsmShader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AsmShaderConverter.AsmVertexShader
{
    internal class VertexShaderDataTypes
    {
        [Flags]
        public enum InOut
        {
            none = 0,
            X = 1,
            Y = 2,
            Z = 4,
            W = 5,
            R = 1,
            G = 2,
            B = 4,
            A = 5
        }
        public class Register
        {
            public string VariableName { get; set; }
            public bool Writeable { get { return false; } }
            public float[] values = new float[4];
            public bool[] isUsed = new bool[4];
            public InOut IO { get; set; }

            public Register(string p)
            {
                string[] values = p.Split('.');
                this.VariableName = values[0];
                if (values.Length > 1)
                    this.IO = GetIoTypes(values[1]);
            }
            public AsmShader.AsmSemantics Semantic { get; set; }

            public float X
            {
                get
                {
                    isUsed[0] = true;
                    return values[0];
                }
                set { values[0] = value; }
            }
            public float Y
            {
                get
                {
                    isUsed[1] = true;
                    return values[1];
                }
                set { values[1] = value; }
            }
            public float Z
            {
                get
                {
                    isUsed[2] = true;
                    return values[2];
                }
                set { values[2] = value; }
            }
            public float W
            {
                get
                {
                    isUsed[3] = true;
                    return values[3];
                }
                set { values[3] = value; }
            }


            internal float GetValue(InOut ioThirdValue)
            {
                switch (ioThirdValue)
                {
                    case InOut.X: return this.X;
                    case InOut.Y: return this.Y;
                    case InOut.Z: return this.Z;
                    case InOut.W: return this.W;
                    default: throw new Exception("Too many Inputs");
                }
            }
        }

        internal static InOut GetIoTypes(string xyzw)
        {
            InOut io = new InOut();
            if (xyzw.Contains("x")) io |= InOut.X;
            if (xyzw.Contains("y")) io |= InOut.Y;
            if (xyzw.Contains("z")) io |= InOut.Z;
            if (xyzw.Contains("w")) io |= InOut.W;

            return io;
        }
    }
}
